package com.casstime.ec.cloud.discount.jms;

import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import javax.jms.JMSException;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import com.casstime.commons.utils.JsonUtil;
import com.google.common.collect.Maps;

import lombok.extern.log4j.Log4j2;
/**
 * 
 * ClassName: MessageSender 
 * Function: (消息推送)
 * Reason: ADD REASON(可选).
 *  
 * @author hongcheng.wu  
 * 2018年1月8日 下午8:15:32
 * @version   
 * @since JDK 1.8
 */
@Component
@Log4j2
public class MessageSender {
	
	private static String smsQueue = "smsQueue";

	private static String msgcenterQueue = "casstime-msgcenter";

	@Value("${icec.context-url}")
	private String context;
	
	@Autowired
	private JmsMessageProducer producer;

	/**
	 * 
	 * sendSMS:发送短信.
	 * @param phoneNums 电话号码列表
	 * @param msg 短信内容
	 * @param phoneNums
	 * @param msg
	 * @author hongcheng.wu
	 * @date 2018年1月8日 下午8:16:33
	 */
	public void sendSMS(List<String> phoneNums, String msg) {
		if (CollectionUtils.isNotEmpty(phoneNums) && StringUtils.isNotBlank(msg)) {
			String messageBody = MessageFormat.format(
			"<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
			+ "<ns0:message xmlns:ns0=\"http://sap/iccrm.com\"><sms><phone>{0}</phone><content>{1}</content><from>ICEC</from></sms></ns0:message>",
					StringUtils.join(phoneNums, ","), msg);
			this.send(MessageType.SMS, messageBody);
			
		} else {
			log.warn("发送短信必要元素为空[phone:{},msg:{}]", JsonUtil.serializer(phoneNums), msg);
		}
	}

	/**
	 * 发送微信通知.
	 * 
	 * @param userLoginIds
	 *            接收用户
	 * @param templateId
	 *            通知模板id
	 * @param url
	 *            通知点击跳转url
	 * @param contents
	 *            模板内容第一个参数为标题，第二个后为关键内容，最后一个为remark
	 * @return
	 * @throws Exception
	 */
	public void sendWechatMsg(List<String> userLoginIds, String templateId, String url, String title, String... contents) {
		if (CollectionUtils.isEmpty(userLoginIds) || StringUtils.isBlank(templateId) || ArrayUtils.isEmpty(contents)) {
			log.warn("接收微信消息用户列表为空或微信模板id为空，[userLoginIds:{}, templateId:{}]", JsonUtil.serializer(userLoginIds), templateId);
			return;
		}
		Map<String, Object> bodyMap = Maps.newHashMap();

		String channel = "WX_TEMP";
		String platform = "WX";
		String type = "RECORD";
		String group = "ORDER";
		String from = "ksxm@casstime.com";
		String timestamp = String.valueOf(System.currentTimeMillis());
		String server = "orders-service";
		Map<String, String> extra = new HashMap<String, String>();
		extra.put("templateId", templateId);
		Map<String, Object> messageBody = new HashMap<String, Object>();
		messageBody.put("channel", channel);
		messageBody.put("platform", platform);
		messageBody.put("type", type);
		messageBody.put("group", group);
		messageBody.put("from", from);
		messageBody.put("timestamp", timestamp);
		messageBody.put("server", server);
		messageBody.put("extra", extra);
		if (StringUtils.isNotBlank(title)) {
			messageBody.put("title", title);
		}
		if (StringUtils.isNotBlank(url)) {
			messageBody.put("url", url);
		}
		List<String> userList = new ArrayList<String>();
		if (CollectionUtils.isNotEmpty(userLoginIds)) {
			for (String i : userLoginIds) {
				if (!userList.contains(i)) {
					userList.add(i);
				}
			}
		}

		Map<String, Object> contentMap = new LinkedHashMap<String, Object>();
		Map<String, String> keyValueMap = new HashMap<String, String>();
		keyValueMap.put("value", contents[0]);
		keyValueMap.put("color", "#333333");
		contentMap.put("first", keyValueMap);
		int size = contents.length;
		for (int index = 1; index < size - 1; index++) {
			keyValueMap = new HashMap<String, String>();
			keyValueMap.put("value", contents[index]);
			keyValueMap.put("color", "#333333");
			contentMap.put("keyword" + index, keyValueMap);
		}
		if (size >= 2) {
			keyValueMap = new HashMap<String, String>();
			keyValueMap.put("value", contents[size - 1]);
			keyValueMap.put("color", "#333333");
			contentMap.put("remark", keyValueMap);
		}

		messageBody.put("content", JsonUtil.serializer(contentMap));
		messageBody.put("to", userList);
		bodyMap.put("messageBody", messageBody);
		this.send(MessageType.WECHAT, bodyMap);
	}

	/**
	 * 发送WEB网页端消息.
	 * @param userLoginIds 用户列表
	 * @param type ACTION|RECORD|NOTICE|TODO  中的一个， ACTION：命令消息，不存储；RECORD，只记录，不通知； NOTICE，通知消息，需要回执（默认为NOTICE）；TODO，待办消息
	 * @param url 消息上的超链接
	 * @param contents 消息内容
	 */
	public void sendWebMsg(List<String> userLoginIds, String type, String url, String title, String contents,
			String group, Map<String, String> extra) {
		this.sendWebOrIMMsg(MessageType.WEB, userLoginIds, type, url, title, contents, group, extra);
	}
	
	/**
	 * 发送小马客户端消息.
	 * @param userLoginIds 用户列表
	 * @param type ACTION|RECORD|NOTICE|TODO  中的一个， ACTION：命令消息，不存储；RECORD，只记录，不通知； NOTICE，通知消息，需要回执（默认为NOTICE）；TODO，待办消息
	 * @param url 消息上的超链接
	 * @param contents 消息内容
	 */
	public void sendIMMsg(List<String> userLoginIds, String type, String url, String title, String contents,
			String group, Map<String, String> extra) {
		this.sendWebOrIMMsg(MessageType.IM, userLoginIds, type, url, title, contents, group, extra);
	}
	
	/**
	 * 发送web端和小马客户端消息.
	 * @param userLoginIds 用户列表
	 * @param type ACTION|RECORD|NOTICE|TODO  中的一个， ACTION：命令消息，不存储；RECORD，只记录，不通知； NOTICE，通知消息，需要回执（默认为NOTICE）；TODO，待办消息
	 * @param url 消息上的超链接
	 * @param contents 消息内容
	 */
	public void sendWebAndIMMsg(List<String> userLoginIds, String type, String url, String title, String contents,
			String group, Map<String, String> extra) {
		this.sendWebOrIMMsg(null, userLoginIds, type, url, title, contents, group, extra);
	}
	
	/**
	 * 发送web端或小马客户端消息.
	 * @param userLoginIds 用户列表
	 * @param type ACTION|RECORD|NOTICE|TODO  中的一个， ACTION：命令消息，不存储；RECORD，只记录，不通知； NOTICE，通知消息，需要回执（默认为NOTICE）；TODO，待办消息
	 * @param url
	 * @param contents 消息内容，支持html，必填
	 */
	private void sendWebOrIMMsg(MessageType messageType, List<String> userLoginIds, String type, String url,
			String title, String contents, String group, Map<String, String> extra) {
		if (CollectionUtils.isEmpty(userLoginIds) || StringUtils.isBlank(contents)) {
			log.warn("接收[{}]消息的用户列表或内容[{}]不能为空", messageType, contents);
			return;
		}
		
		String platform = "DESKTOP|WEB|APP";
		if (messageType == MessageType.WEB) {
			platform = "WEB";
		} else if (messageType == MessageType.IM) {
			platform = "DESKTOP";
		}
		Map<String, Object> bodyMap = Maps.newHashMap();

		String channel = "WS";
		String from = "ksxm@casstime.com";
		String timestamp = String.valueOf(System.currentTimeMillis());
		String server = "ORDER";
		Map<String, Object> messageBody = new HashMap<String, Object>();
		messageBody.put("channel", channel);
		messageBody.put("platform", platform);
		messageBody.put("type", StringUtils.defaultIfBlank(type, "NOTICE"));
		messageBody.put("group", group);
		messageBody.put("from", from);
		messageBody.put("timestamp", timestamp);
		messageBody.put("server", server);
		if (extra == null) {
			messageBody.put("extra", new HashMap<String, String>());
		} else {
			messageBody.put("extra", extra);
		}
		if (StringUtils.isNotBlank(title)) {
			messageBody.put("title", title);
		}
		if (StringUtils.isNotBlank(url)) {
			messageBody.put("url", context + url);
		}
		List<String> userList = new ArrayList<String>();
		if (CollectionUtils.isNotEmpty(userLoginIds)) {
			for (String i : userLoginIds) {
				if (!userList.contains(i)) {
					userList.add(i);
				}
			}
		}

		messageBody.put("content", contents);
		messageBody.put("to", userList);
		bodyMap.put("messageBody", messageBody);
		this.send(MessageType.WEB, bodyMap);
	}
	
	private void send(MessageType messageType, Map<String, Object> bodyMap) {
		/**
		 * <pre>
		 * messageBody:
		 * {
		 *     channel: String,                    // WS|SMS|EMAIL|WX_TEMP 中的一个, 默认为WS（websocket）
		 *     platform: String,                   // DESKTOP|WEB|ANROID|IOS|WX|ALL 中的一个，默认为 'ALL'
		 *     type: String,                       // ACTION|RECORD|NOTICE|TODO  
		 *     									//中的一个， ACTION：命令消息，不存储；RECORD，只记录，不通知； NOTICE，通知消息，需要回执（默认为NOTICE）；TODO，待办消息
		 *     group: String,                      // INQUIRY|ORDER 中的一个。标识消息分组，目前为询价单或订单
		 *     from: String,                       // ksxm@casstime.com
		 *     to: String ,          // 单个或多个用户  （必填）
		 *     title: String,                      // 标题，可选
		 *     content: String,                    // 内容，支持html    （必填）
		 *     url: String,                        // url 跳转链接
		 *     timestamp: Number|String,           // 消息时间戳 ms,数字或字符串  （必填）
		 *     delay: Number，                      // 延迟发送时间ms, 系统收到消息后延时发送,如 5000 即延迟5S发送
		 *     server: String,                     // 服务名称        
		 *     extra: Any                          // 扩展，可以为任意值（String|Array|Object|...）
		 * }
		 * </pre>
		 */
		String message = JsonUtil.serializer(bodyMap);
		this.send(messageType, message);
	}
	
	private void send(MessageType messageType, String message) {
		if (StringUtils.isNotBlank(message)) {
			try {
				producer.sendQueueMessage(messageType.getValue(), message);
				log.warn("[{} Message] body:{}", messageType, message);
			} catch (JMSException e) {
				log.warn("发送{}失败,body:{}", messageType, message, e);
			}
		} else {
			log.warn("消息体为空");
		}
	}



	@Value("${spring.activemq.queue.smsQueue}")
	public void setSmsQueue(String queue) {
		smsQueue = queue;
	}

	@Value("${spring.activemq.queue.msgcenterQueue}")
	public void setMsgcenterQueue(String queue) {
		msgcenterQueue = queue;
	}
	
	/**
	 * ClassName: MessageType 
	 * Function: (消息类型枚举).
	 * @version MessageSender  
	 * @since JDK 1.8
	 */
	private enum MessageType {
		SMS(smsQueue), WECHAT(msgcenterQueue), WEB(msgcenterQueue), IM(msgcenterQueue);
		private String value;

		MessageType(String value) {
			this.value = value;
		}

		public String getValue() {
			return value;
		}
	}
}
